import "./utils/loadEnv"
import fs from "fs"
import path from "path"
import { fileURLToPath } from "url"
import { createProxyMiddleware } from "http-proxy-middleware"
import bodyParser from "body-parser"
import cookieParser from "cookie-parser"
import timeout from "connect-timeout"
import express, { Application } from "express"
import { I18n } from "i18n"
import languages from "./config/languages"
import Router from "./router"
import loggerTool from "./utils/logger"

import { createBundleRender } from "./render"

const logger = loggerTool(import.meta.url)
const protocol = process.env.PROTOCOL || "http"
const port = process.env.PORT || 8680
const isProd = process.env.NODE_ENV === "production"

// 在ts文件里不能直接使用__dirname，所以需要使用这种方法
const __dirname = path.dirname(fileURLToPath(import.meta.url))

async function createServer() {
  const app: Application = express()

  // @ts-ignore
  const version = isProd ? __VERSION__ : process.env.npm_package_version

  const i18n = new I18n({
    objectNotation: true,
    defaultLocale: "en",
    retryInDefaultLocale: true,
    locales: languages,
    updateFiles: false,
    directory: path.join(__dirname, "locales")
  })

  const apiProxyBaseUrl = process.env.VITE_API_BASE_URL
  // 代理域名
  apiProxyBaseUrl &&
    app.use(
      "/api",
      createProxyMiddleware({
        target: apiProxyBaseUrl,
        changeOrigin: true,
        pathRewrite: {
          "^/api": ""
        }
      })
    )
  app.use(
    "/trackApi",
    createProxyMiddleware({
      target: process.env.VITE_TRACK_API_BASE_URL,
      changeOrigin: true,
      pathRewrite: {
        "^/trackApi": ""
      }
    })
  )

  app.use(cookieParser())

  app.use(timeout("60s"))

  app.use(bodyParser.json()) // 处理 json 格式
  app.use(bodyParser.urlencoded({ extended: false })) // 处理 urlencoded 格式

  await createBundleRender(app)

  app.use(i18n.init)

  app.use(Router)

  if (isProd) {
    // 监听服务异常
    app.use(function onError(err, req, res, next) {
      logger.error(`AppOnError ${err.stack}`)
      res.status(500).send('500 error')
    })
  }

  if (protocol === "https") {
    const privateKey = fs.readFileSync("./server/cert/patpat.site+6-key.pem", "utf8")
    const certificate = fs.readFileSync("./server/cert/patpat.site+6.pem", "utf8")
    const credentials = { key: privateKey, cert: certificate }
    const https = await import("https")
    https.createServer(credentials, app).listen(port, () => {
      logger.info(`\x1b[42;30m服务启动成功:\x1b[0;32m \x1b[4m${protocol}://localhost:${port}\x1b[0m`)
    })
  } else {
    app.listen(port, () => {
      logger.info(`\x1b[42;30m 服务启动成功:\x1b[0;32m \x1b[4m${protocol}://localhost:${port}\x1b[0m`)
    })
  }
}

createServer()
